{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Rk</th>\n",
       "      <th>Player</th>\n",
       "      <th>Pos</th>\n",
       "      <th>Age</th>\n",
       "      <th>Tm</th>\n",
       "      <th>G</th>\n",
       "      <th>MP</th>\n",
       "      <th>PER</th>\n",
       "      <th>TS%</th>\n",
       "      <th>3PAr</th>\n",
       "      <th>...</th>\n",
       "      <th>TOV%</th>\n",
       "      <th>USG%</th>\n",
       "      <th>OWS</th>\n",
       "      <th>DWS</th>\n",
       "      <th>WS</th>\n",
       "      <th>WS/48</th>\n",
       "      <th>OBPM</th>\n",
       "      <th>DBPM</th>\n",
       "      <th>BPM</th>\n",
       "      <th>VORP</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Quincy Acy</td>\n",
       "      <td>PF</td>\n",
       "      <td>22</td>\n",
       "      <td>TOR</td>\n",
       "      <td>29</td>\n",
       "      <td>342</td>\n",
       "      <td>15.9</td>\n",
       "      <td>0.632</td>\n",
       "      <td>0.027</td>\n",
       "      <td>...</td>\n",
       "      <td>15.6</td>\n",
       "      <td>14.7</td>\n",
       "      <td>0.7</td>\n",
       "      <td>0.4</td>\n",
       "      <td>1.1</td>\n",
       "      <td>0.157</td>\n",
       "      <td>-0.6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>Jeff Adrien</td>\n",
       "      <td>PF</td>\n",
       "      <td>26</td>\n",
       "      <td>CHA</td>\n",
       "      <td>52</td>\n",
       "      <td>713</td>\n",
       "      <td>13.4</td>\n",
       "      <td>0.493</td>\n",
       "      <td>0.012</td>\n",
       "      <td>...</td>\n",
       "      <td>13.1</td>\n",
       "      <td>15.6</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.4</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.064</td>\n",
       "      <td>-2.9</td>\n",
       "      <td>-0.4</td>\n",
       "      <td>-3.3</td>\n",
       "      <td>-0.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>Arron Afflalo</td>\n",
       "      <td>SF</td>\n",
       "      <td>27</td>\n",
       "      <td>ORL</td>\n",
       "      <td>64</td>\n",
       "      <td>2307</td>\n",
       "      <td>13.0</td>\n",
       "      <td>0.527</td>\n",
       "      <td>0.265</td>\n",
       "      <td>...</td>\n",
       "      <td>12.1</td>\n",
       "      <td>22.5</td>\n",
       "      <td>1.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.042</td>\n",
       "      <td>-0.4</td>\n",
       "      <td>-1.9</td>\n",
       "      <td>-2.3</td>\n",
       "      <td>-0.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>Josh Akognon</td>\n",
       "      <td>PG</td>\n",
       "      <td>26</td>\n",
       "      <td>DAL</td>\n",
       "      <td>3</td>\n",
       "      <td>9</td>\n",
       "      <td>15.3</td>\n",
       "      <td>0.625</td>\n",
       "      <td>0.500</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>20.3</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.196</td>\n",
       "      <td>4.3</td>\n",
       "      <td>-4.9</td>\n",
       "      <td>-0.6</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Cole Aldrich</td>\n",
       "      <td>C</td>\n",
       "      <td>24</td>\n",
       "      <td>TOT</td>\n",
       "      <td>45</td>\n",
       "      <td>388</td>\n",
       "      <td>11.1</td>\n",
       "      <td>0.563</td>\n",
       "      <td>0.000</td>\n",
       "      <td>...</td>\n",
       "      <td>20.6</td>\n",
       "      <td>12.7</td>\n",
       "      <td>0.1</td>\n",
       "      <td>0.4</td>\n",
       "      <td>0.6</td>\n",
       "      <td>0.070</td>\n",
       "      <td>-4.4</td>\n",
       "      <td>0.4</td>\n",
       "      <td>-3.9</td>\n",
       "      <td>-0.2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 27 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   Rk         Player Pos  Age   Tm   G    MP   PER    TS%   3PAr  ...  TOV%  \\\n",
       "0   1     Quincy Acy  PF   22  TOR  29   342  15.9  0.632  0.027  ...  15.6   \n",
       "1   2    Jeff Adrien  PF   26  CHA  52   713  13.4  0.493  0.012  ...  13.1   \n",
       "2   3  Arron Afflalo  SF   27  ORL  64  2307  13.0  0.527  0.265  ...  12.1   \n",
       "3   4   Josh Akognon  PG   26  DAL   3     9  15.3  0.625  0.500  ...   0.0   \n",
       "4   5   Cole Aldrich   C   24  TOT  45   388  11.1  0.563  0.000  ...  20.6   \n",
       "\n",
       "   USG%  OWS  DWS   WS  WS/48  OBPM  DBPM  BPM  VORP  \n",
       "0  14.7  0.7  0.4  1.1  0.157  -0.6   1.0  0.5   0.2  \n",
       "1  15.6  0.5  0.4  1.0  0.064  -2.9  -0.4 -3.3  -0.2  \n",
       "2  22.5  1.5  0.5  2.0  0.042  -0.4  -1.9 -2.3  -0.2  \n",
       "3  20.3  0.0  0.0  0.0  0.196   4.3  -4.9 -0.6   0.0  \n",
       "4  12.7  0.1  0.4  0.6  0.070  -4.4   0.4 -3.9  -0.2  \n",
       "\n",
       "[5 rows x 27 columns]"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# read data set 'nba_2013.csv'\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.neighbors import KNeighborsRegressor as nr\n",
    "from sklearn.model_selection import train_test_split as tts\n",
    "import math\n",
    "# import data\n",
    "data_path = 'nba_2013.csv'\n",
    "df_nba = pd.read_csv(data_path)\n",
    "df_nba.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Rk        0\n",
       "Player    0\n",
       "Pos       0\n",
       "Age       0\n",
       "Tm        0\n",
       "G         0\n",
       "MP        0\n",
       "PER       1\n",
       "TS%       4\n",
       "3PAr      4\n",
       "FTr       4\n",
       "ORB%      1\n",
       "DRB%      1\n",
       "TRB%      1\n",
       "AST%      1\n",
       "STL%      1\n",
       "BLK%      1\n",
       "TOV%      3\n",
       "USG%      1\n",
       "OWS       0\n",
       "DWS       0\n",
       "WS        0\n",
       "WS/48     1\n",
       "OBPM      0\n",
       "DBPM      0\n",
       "BPM       0\n",
       "VORP      0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# sum how many nan in the data\n",
    "df_nba.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Rk        0\n",
       "Player    0\n",
       "Pos       0\n",
       "Age       0\n",
       "Tm        0\n",
       "G         0\n",
       "MP        0\n",
       "PER       0\n",
       "TS%       0\n",
       "3PAr      0\n",
       "FTr       0\n",
       "ORB%      0\n",
       "DRB%      0\n",
       "TRB%      0\n",
       "AST%      0\n",
       "STL%      0\n",
       "BLK%      0\n",
       "TOV%      0\n",
       "USG%      0\n",
       "OWS       0\n",
       "DWS       0\n",
       "WS        0\n",
       "WS/48     0\n",
       "OBPM      0\n",
       "DBPM      0\n",
       "BPM       0\n",
       "VORP      0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# use mean method to imputate missing values\n",
    "df_nba.fillna(df_nba.mean(), inplace = True)\n",
    "df_nba.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# split data to training/testing data to 4:1, use several knn (k=5, k=sqrt(n), k=50) \n",
    "# models to predict player rank, evaluation matrics is mse\n",
    "# set up the data to test and train\n",
    "factor = df_nba[['Age','G', 'MP', 'PER', 'TS%', '3PAr', 'FTr', 'ORB%', 'DRB%', \n",
    "            'TRB%', 'AST%', 'STL%', 'BLK%','TOV%', 'USG%', 'OWS', 'DWS', \n",
    "            'WS', 'WS/48', 'OBPM', 'DBPM','BPM', 'VORP']]\n",
    "predict = df_nba['Rk']\n",
    "factor_train, factor_test, predict_train, predict_test = tts(factor, predict, test_size=0.2, random_state=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# define a function to test which knn is better\n",
    "def fit_and_test(knn):\n",
    "    knn_model = nr(n_neighbors = knn)\n",
    "    knn_model.fit(factor_train, predict_train)\n",
    "    result = knn_model.predict(factor_test)\n",
    "    return (((result- predict_test) ** 2).sum()) / len(predict_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "if knn = 2, mse = 21918.24904347826\n",
      "if knn = square of n, mse = 19493.943963179092\n",
      "if knn = 50, mse = 19494.240066086957\n"
     ]
    }
   ],
   "source": [
    "# test different knn\n",
    "print(\"if knn = 2, mse = \" + str(fit_and_test(5)))\n",
    "print(\"if knn = square of n, mse = \" + str(fit_and_test(int(math.sqrt(df_nba.shape[0])))))\n",
    "print(\"if knn = 50, mse = \" + str(fit_and_test(50)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
